home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
PROGENV
/
Reference.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-27
|
4KB
|
258 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Reference.h"
#include "Class.h"
#include "ObjectTable.h"
#include "String.h"
#include "Exception.h"
//---- reference ---------------------------------------------------------------
NewMetaImpl(Ref, Object, (T(type), T(offset), T(len), TP(cla), TX(base)));
Ref::Ref()
{
base= 0;
type= offset= 0;
len= -1;
cla= 0;
}
Ref::Ref(void *b, int t, int o, int l, Class *c, bool g, bool lg)
{
base= b;
type= t;
offset= o;
len= l;
cla= c;
SetFlag(eRefGlobal, g);
SetFlag(eRefLenGlobal, lg);
}
Ref::Ref(Object &op)
{
base= &op;
type= offset= 0;
len= -1;
cla= op.IsA();
}
Ref::Ref(Object *&op)
{
base= &op;
type= T_PTR;
offset= 0;
len= -1;
cla= op->IsA();
}
Ref::Ref(const Ref &ref)
{
base= ref.base;
type= ref.type;
offset= ref.offset;
len= ref.len;
cla= ref.cla;
}
void Ref::operator=(Ref ref)
{
base= ref.base;
type= ref.type;
offset= ref.offset;
len= ref.len;
cla= ref.cla;
}
bool Ref::IsEqual(Object *op)
{
if (op->IsKindOf(Ref))
return (((Ref*)op)->base == base) && (((Ref*)op)->offset == offset);
return FALSE;
}
bool Ref::IsObject()
{
if (type & (T_ARR|T_VEC|T_PTR2))
return FALSE;
return cla && cla->TestFlag(eClassObject) && (type == 0)
&& ObjectTable::PtrIsValid((Object*)base);
}
void *Ref::Addr()
{
if (IsGlobal())
return (void*) offset;
return (void*) ((u_long)base + (u_long)offset);
}
int Ref::Size()
{
if (type == 0 && cla)
return cla->Size();
return sizeof(void*);
}
int Ref::Length()
{
int l= 0;
if (type & T_ARR)
return len;
if (type & T_VEC) {
int *ll;
if (TestFlag(eRefLenGlobal))
ll= (int*) len;
else
ll= (int*) ((u_long) base + (u_long) len);
TRY {
l= *ll;
} CATCH(ex) {
return -2;
} ENDTRY
return l;
}
if (type & T_STR) {
int s;
if ((type & ~T_STR) == 0 && cla)
s= cla->Size();
else
s= sizeof(void*);
void *val= (void*) *((u_long*) Addr());
if (val == 0)
return -1;
TRY {
switch (s) {
case 1:
char *cp= (char*)val;
while (*cp++)
l++;
break;
case 2:
short *sp= (short*)val;
while (*sp++)
l++;
break;
case 4:
int *ip= (int*)val;
while (*ip++)
l++;
break;
}
} CATCH(ex) {
return -2;
} ENDTRY
return l;
}
return -1;
}
Ref *Ref::Deref()
{
void *oo= 0, *oo2= 0;
if (type == 0) { // simple
if (IsObject())
return new Ref(Addr(), type, 0, Length(), cla);
return 0;
}
if (type & T_ARR) // inline array of simple
return new Ref(Addr(), type & ~T_ARR, 0, Length(), cla);
TRY {
oo= (void*) *((int*)Addr());
} CATCH(ex) {
return 0;
} ENDTRY
TRY {
oo2= (void*) *((int*)oo);
} CATCH(ex) {
return 0;
} ENDTRY
if (oo == 0)
return 0;
if (type & (T_VEC|T_STR|T_PTR))
return new Ref(oo, type & ~(T_VEC|T_STR|T_PTR), 0, Length(), cla);
if (type & T_PTR2)
return new Ref(oo, type & ~T_PTR2, 0, -1, cla);
return 0; // cannot happen
}
char *Ref::Value(char *name)
{
int l;
void *val;
bool isptr= TRUE,
getvalue= FALSE;
char *pre= " ",
*post,
buf[400],
*bp;
if ((type & T_PTR) && (type & T_PTR2))
pre= "**";
else if ((type & T_PTR) || (type & T_PTR2))
pre= " *";
switch (l= Length()) {
case -2:
post= "[<ill addr>]";
break;
case -1:
post= "";
break;
default:
post= form("[%d]", l);
break;
}
memset(buf, 0, 400);
bp= buf;
val= Addr();
if (type & T_ARR) {
strcpy(bp, "<inline> ");
bp+= strlen(bp);
if (! (type & T_PTR2))
getvalue= TRUE;
} else if (type == 0) {
isptr= FALSE;
getvalue= TRUE;
} else {
val= *((void**) val);
if (val) {
strcpy(bp, form("0x%08x ", val));
bp+= strlen(bp);
if ((type & (T_PTR|T_VEC|T_STR)) && !(type & T_PTR2) || (type == T_PTR2))
getvalue= TRUE;
} else
strcpy(bp, "<nil>");
}
if (getvalue) {
TRY {
cla->Show(bp, val, l, isptr);
} CATCH(ex) {
strcat(bp, "<illegal address>");
} ENDTRY
}
return form(" %-14.14s %1s%-18.18s: %s",
cla->Name(),
pre,
form("%s%s%s ", IsGlobal() ? "::" : "", name, post),
buf);
}